﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ComicIsland.Common;
using ComicIsland.Common.Entities.LocalJson;
using ComicIsland.Common.StorageHelper;

/**
 * 创建时间：2015/1/16 15:40:42
 * 作者：yong.blackcore
 * Email：itblackhole@outlook.com
 * QQ：50404503
 */
namespace ComicIsland.App.CIHelper
{
    /// <summary>
    /// 书架
    /// </summary>
    public class LocalBookcaseInfoHelper
    {
        public string FilePath { get; private set; }
        public LocalBookcaseInfoHelper()
        {
            this.FilePath = "LocalBookcaseInfo";
        }

        /// <summary>
        /// 添加漫画至收藏夹
        /// </summary>
        /// <param name="bookcaseInfo"></param>
        /// <returns></returns>
        public bool Add(LocalBookcaseInfo bookcaseInfo)
        {
            bool result = false;
            try
            {
                if (!(bookcaseInfo != null && bookcaseInfo.ComicId > 0 && bookcaseInfo.BookId > 0))
                {
                    LogHelper.LogError("添加至收藏夹的漫画参数不正确！", this.GetType(), MethodBase.GetCurrentMethod());
                    return false;
                }
                //
                ObservableCollection<LocalBookcaseInfo> items = null;
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                    }
                }
                //
                if (items != null && items.Count > 0)
                {
                    var item = (from p in items where p.ComicId == bookcaseInfo.ComicId select p).FirstOrDefault<LocalBookcaseInfo>();
                    if (item == null)
                    {
                        items.Add(bookcaseInfo);
                    }
                }
                else
                {
                    items = new ObservableCollection<LocalBookcaseInfo>();
                    items.Add(bookcaseInfo);
                }
                //
                string jsons = JSONHelper.Serialize<ObservableCollection<LocalBookcaseInfo>>(items);
                if (!string.IsNullOrWhiteSpace(jsons))
                {
                    IsolatedStorageHelper.Instance.WriteText(jsons, this.FilePath, true);
                    result = true;
                }
            }
            catch { }
            return result;
        }

        public bool Update(LocalBookcaseInfo bookcaseInfo)
        {
            bool result = false;
            try
            {
                if (!(bookcaseInfo != null && bookcaseInfo.ComicId > 0 && bookcaseInfo.BookId > 0))
                {
                    LogHelper.LogError("更新至收藏夹的漫画参数不正确！", this.GetType(), MethodBase.GetCurrentMethod());
                    return false;
                }
                //
                ObservableCollection<LocalBookcaseInfo> items = null;
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                    }
                }
                //
                if (items != null && items.Count > 0)
                {
                    var item = (from p in items where p.ComicId == bookcaseInfo.ComicId select p).FirstOrDefault<LocalBookcaseInfo>();
                    if (item != null)
                    {
                        item.ComicTitle = bookcaseInfo.ComicTitle;
                        item.Coverurl = bookcaseInfo.Coverurl;
                        item.BookId = bookcaseInfo.BookId;
                        item.SourceName = bookcaseInfo.SourceName;
                        item.PartId = bookcaseInfo.PartId;
                        item.PartName = bookcaseInfo.PartName;
                        item.LocalUpdateDate = bookcaseInfo.LocalUpdateDate;
                        item.IsSync = bookcaseInfo.IsSync;
                        item.Status = bookcaseInfo.Status;
                        string jsons = JSONHelper.Serialize<ObservableCollection<LocalBookcaseInfo>>(items);
                        if (!string.IsNullOrWhiteSpace(jsons))
                        {
                            IsolatedStorageHelper.Instance.WriteText(jsons, this.FilePath, true);
                            result = true;
                        }
                    }
                }
            }
            catch { }
            return result;
        }

        /// <summary>
        /// 更新章节状态
        /// </summary>
        /// <param name="bookcaseInfos"></param>
        /// <param name="hasUpdate"></param>
        /// <returns></returns>
        public bool UpdateChapterUpdateFlag(ObservableCollection<LocalBookcaseInfo> bookcaseInfos, bool hasUpdate = false)
        {
            bool result = false;
            try
            {
                if (!(bookcaseInfos != null && bookcaseInfos.Count > 0))
                {
                    return false;
                }
                //
                ObservableCollection<LocalBookcaseInfo> items = null;
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                    }
                }
                //
                if (items != null && items.Count > 0)
                {
                    foreach (var bookcaseInfo in bookcaseInfos)
                    {
                        if (bookcaseInfo == null)
                            continue;
                        var item = (from p in items where p.BookId == bookcaseInfo.BookId && p.ComicTitle.Equals(bookcaseInfo.ComicTitle) select p).FirstOrDefault<LocalBookcaseInfo>();
                        if (item != null)
                        {
                            item.LocalUpdateDate = DateTime.Now.ToString(KEYS.DATE_FORMAT_YMD);
                            item.UpdateChapterFlag = hasUpdate;
                        }
                    }
                    //更新数据
                    string jsons = JSONHelper.Serialize<ObservableCollection<LocalBookcaseInfo>>(items);
                    if (!string.IsNullOrWhiteSpace(jsons))
                    {
                        IsolatedStorageHelper.Instance.WriteText(jsons, this.FilePath, true);
                        result = true;
                    }
                }
            }
            catch { }
            return result;
        }

        /// <summary>
        /// 漫画是否存在书架中
        /// </summary>
        /// <param name="comicId"></param>        
        /// <returns></returns>
        public bool IsExist(int comicId)
        {
            bool result = false;
            try
            {
                ObservableCollection<LocalBookcaseInfo> items = null;
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                    }
                }
                //
                if (items != null && items.Count > 0)
                {
                    var item = (from p in items where p.ComicId == comicId select p).FirstOrDefault<LocalBookcaseInfo>();
                    if (item != null)
                    {
                        result = true;
                    }
                }
            }
            catch { }
            finally { }
            return result;
        }

        public ObservableCollection<LocalBookcaseInfo> GetAll(List<LocalBookcaseStatus> statuses, Boolean? IsSync = null)
        {
            ObservableCollection<LocalBookcaseInfo> result = null;
            try
            {
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        var items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                        if (items != null && items.Count > 0)
                        {
                            List<LocalBookcaseInfo> lists = new List<LocalBookcaseInfo>();
                            if (statuses != null && statuses.Count() > 0)
                            {
                                foreach (var status in statuses)
                                {
                                    var tmpLists = (from p in items where p.Status.Equals(status.ToString()) && (IsSync == null ? true : p.IsSync == IsSync) select p).ToList<LocalBookcaseInfo>();
                                    if (tmpLists != null && tmpLists.Count > 0)
                                    {
                                        foreach (var tmpList in tmpLists)
                                        {
                                            lists.Add(tmpList);
                                        }
                                    }
                                }
                            }
                            if (lists != null && lists.Count > 0)
                            {
                                result = new ObservableCollection<LocalBookcaseInfo>(lists);
                            }
                        }
                    }
                }
            }
            catch { }
            return result;
        }

        private bool GetCondition(LocalBookcaseInfo item, IEnumerable<LocalBookcaseStatus> statuses)
        {
            bool boolResult = true;
            if (statuses != null && statuses.Count() > 0)
            {
                foreach (var status in statuses)
                {
                    boolResult &= item.Status.Equals(status.ToString());
                }
            }
            return boolResult;
        }



        public LocalBookcaseInfo Get(int comicId)
        {
            LocalBookcaseInfo result = null;
            try
            {
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        var items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                        if (items != null && items.Count > 0)
                        {
                            result = (from p in items where p.ComicId == comicId select p).FirstOrDefault<LocalBookcaseInfo>();
                        }
                    }
                }

            }
            catch { }
            return result;
        }




        public bool Remove(int comicId)
        {
            bool result = false;
            try
            {
                if (IsolatedStorageHelper.Instance.FileExists(this.FilePath))
                {
                    string json = IsolatedStorageHelper.Instance.ReadText(this.FilePath);
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        var items = JSONHelper.Deserialize<ObservableCollection<LocalBookcaseInfo>>(json);
                        if (!(items != null && items.Count > 0))
                            return false;

                        for (int i = 0; i < items.Count; i++)
                        {
                            var item = items[i];
                            if (item == null)
                                continue;
                            items.Remove(item);
                        }

                        var saveJson = JSONHelper.Serialize<ObservableCollection<LocalBookcaseInfo>>(items);
                        if (!string.IsNullOrWhiteSpace(saveJson))
                        {
                            IsolatedStorageHelper.Instance.WriteText(saveJson, this.FilePath, true);
                        }
                        result = true;
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogInfo(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            return result;
        }

    }

    public static class PredicateExtensions
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
        }
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.And(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }
}
